#include    "Api.h"
#include    "Json.h"

#include    <algorithm>
#include    <fstream>
#include    <vector>

#define     ARG_CONFIG              L"config"
#define     ARG_CONFIG_DEFUALT_USER L"--default-user"
#define     ARG_INSTALL             L"install"
#define     ARG_UNINSTALL           L"uninstall"
#define     ARG_RUN                 L"run"
#define     ARG_RUN_C               L"-c"

int wmain(int argc, const wchar_t * argv[]) {
    /** Read distro configuration from file */
    std::ifstream ifs("launcher.json");
    if (!ifs.is_open()) {
        wprintf(L"Missing configuration launcher.json\n");
        return 0;
    }

    Json::CharReaderBuilder builder;
    Json::Value config;
    bool ok = Json::parseFromStream(builder, ifs, &config, nullptr);
    if (!ok || !config["distro"].isString() || !config["repo"].isString()) {
        wprintf(L"Bad configuration launcher.json\n");
        return 0;
    }

    Api api(config["distro"].asString(), config["repo"].asString());

    /** Put command line arguments into array */
    std::vector<std::wstring> args;
    for (int i = 1; i < argc; ++i) args.push_back(argv[i]);

#define HASARG(ARG) (std::find(args.begin(), args.end(), ARG) != args.end())

    /** Check environment */
    if (!api.CheckEnvironment()) {
        wprintf(L"The Windows Subsystem for Linux optional component is not enabled. Please enable it and try again.\n");
        wprintf(L"For more information visit: https://aka.ms/wslusers\n");
        return 0;
    }

    /** Is uninstall */
    if (HASARG(ARG_UNINSTALL)) {
        if (api.IsRegistered()) api.Uninstall();
        return 0;
    }

    /** Install this distribution if it is NOT ready */
    if (!api.IsRegistered()) {
        if (!api.Install()) {
            wprintf(L"Install failed. Press Enter to exit\n");
            while (getchar() != '\n') continue;
            return 0;
        }
    } else if (HASARG(ARG_INSTALL)) {
        wprintf(L"The distribution installation has become corrupted.\n");
        wprintf(L"Please select Reset from App Settings or uninstall and reinstall the app.\n");
        return 0;
    }

    /** Start wsl */
    DWORD exit_code;
    if (args.empty()) {
        api.LaunchInteractive(L"", false, &exit_code);
    } else if (HASARG(ARG_RUN) || HASARG(ARG_RUN_C)) {
        std::wstring cmd;
        for (size_t i = 1; i < args.size(); ++i) {
            cmd += L" ";
            cmd += args[i];
        }
        api.LaunchInteractive(cmd.c_str(), true, &exit_code);
    } else if (HASARG(ARG_CONFIG)) {
        if (HASARG(ARG_CONFIG_DEFUALT_USER)) {
            if (args.size() == 3) api.SetDefaultUser(args[2]);
        }
    } else {
        wprintf(L"Launches or configures a Linux distribution.\n\n");
        wprintf(L"Usage: \n");
        wprintf(L"  <no args>\n    Launches the user's default shell in the user's home directory.\n\n");
        wprintf(L"  install\n    Install the distribuiton and do not launch the shell when complete.\n\n");
        wprintf(L"  uninstall\n    Uninstall this distribution\n\n");
        wprintf(L"  run/-c <command line>\n    Run the provided command line in the current working directory. If no\n    command line is provided, the default shell is launched.\n\n");
        wprintf(L"  config [setting [value]]\n    Configure settings for this distribution.\n    Settings:\n      --default-user <username>  Sets the default user to <username>. This must be an existing user.\n\n");
    }

#undef HASARG

    return 0;
}